package org.mineground.commands.irc;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.jibble.pircbot.Colors;
import org.jibble.pircbot.User;
import org.mineground.Main;
import org.mineground.Utilities;
import org.mineground.handlers.irc.CommandExecutor;
import org.mineground.handlers.irc.UserLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @name RangeException.java
 * @author Daniel Koenen (2012)
 */
public class RangeException implements CommandExecutor{
    private static final Logger ExceptionLogger = LoggerFactory.getLogger(RangeException.class);
    
    @Override
    public void onCommand(User sender, UserLevel level, String channel, String command, String arguments[]) {
	if (level.compareTo(UserLevel.IRC_OP) < 0) {
	    return;
        }

        if (arguments.length < 3) {
            Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Usage:" + Colors.NORMAL + " !rangeexception [add/remove] [rangeId] [playerName]");
	    return;
	}
        
        if (!Utilities.isNumeric(arguments[1])) {
            Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Usage:" + Colors.NORMAL + " !rangeexception [add/remove] [rangeId] [playerName]");
	    return;
	}
        
        try {
            boolean doesExist = false;
            int banId = Integer.parseInt(arguments[1]);
        
            StringBuilder queryBuilder = new StringBuilder();
            queryBuilder.append("SELECT e.ban_id, p.player_id FROM lvm_ip_ban_exceptions e ");
            queryBuilder.append("LEFT JOIN lvm_players p ON e.player_id = p.player_id ");
            queryBuilder.append("WHERE p.login_name = ? AND e.ban_id = ?");

            PreparedStatement queryStatement = Main.getInstance().getDatabaseHandler().getConnection().prepareStatement(queryBuilder.toString());
            queryStatement.setString(1, arguments[2]);
            queryStatement.setInt(2, banId);
            queryStatement.execute();
            
            ResultSet queryResult = queryStatement.getResultSet();
            if (queryResult.next()) {
                doesExist = true;
            }
            
            if (arguments[0].equalsIgnoreCase("add")) {
                if (doesExist) {
                    Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Error: That exception already exists.");
                    return;
                }
                
                if (!doesBanExist(banId)) {
                    Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Error: That ban doesn't exist.");
                    return;
                }
                
                int profileId = getProfileId(arguments[2]);
                
                if (profileId == -1) {
                    Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Error: That player never joined LVM.");
                    return;
                }
                
                queryBuilder = new StringBuilder();
                queryBuilder.append("INSERT INTO lvm_ip_ban_exceptions (ban_id, player_id) VALUES (?, ?)");
                queryStatement = Main.getInstance().getDatabaseHandler().getConnection().prepareStatement(queryBuilder.toString());
                queryStatement.setInt(1, banId);
                queryStatement.setInt(2, profileId);
                queryStatement.execute();
                
                Main.getInstance().getIRCHandler().sendMessage(channel, Colors.DARK_GREEN + "Range exception has been added for " + arguments[2] + ".");
                queryStatement.close();
                return;
            }
            
            if (arguments[0].equalsIgnoreCase("remove")) {
                if (!doesExist) {
                    Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Error: That exception doesn't exist.");
                    return;
                }
                
                int profileId = getProfileId(arguments[2]);
                
                if (profileId == -1) {
                    Main.getInstance().getIRCHandler().sendMessage(channel, Colors.RED + "* Error: That player never joined LVM.");
                    return;
                }
                
                queryBuilder = new StringBuilder();
                queryBuilder.append("DELETE FROM lvm_ip_ban_exceptions WHERE player_id = ? AND ban_id = ?");
                queryStatement = Main.getInstance().getDatabaseHandler().getConnection().prepareStatement(queryBuilder.toString());
                queryStatement.setInt(1, profileId);
                queryStatement.setInt(2, banId);
                queryStatement.execute();
            
                Main.getInstance().getIRCHandler().sendMessage(channel, Colors.DARK_GREEN + "Range exception has been removed for " + arguments[2] + ".");
                queryStatement.close();
            }
        }
        
        catch (Exception exception) {
            exception.printStackTrace();
        }
    }
    
    private int getProfileId(String playerName) {
        try {
            PreparedStatement queryStatement = Main.getInstance().getDatabaseHandler().getConnection().prepareStatement("SELECT player_id FROM lvm_players WHERE login_name = ?");
            queryStatement.setString(1, playerName);
            queryStatement.execute();
            
            ResultSet queryResult = queryStatement.getResultSet();
            if (queryResult.next()) {
                return queryResult.getInt(1);
            }
        }
        
        catch (Exception exception) {
            ExceptionLogger.error("Exception caught", exception);
        }
        
        return -1;
    }
    
    private boolean doesBanExist(int banId) {
        try {
            PreparedStatement queryStatement = Main.getInstance().getDatabaseHandler().getConnection().prepareStatement("SELECT ban_id FROM lvm_ip_bans WHERE ban_id = ?");
            queryStatement.setInt(1, banId);
            queryStatement.execute();
            
            ResultSet queryResult = queryStatement.getResultSet();
            if (queryResult.next()) {
                return true;
            }
        }
        
        catch (Exception exception) {
            ExceptionLogger.error("Exception caught", exception);
        }
        
        return false;
    }
}
